package types

import (
	"hundsun.com/hsl/hschain/common/keystore"
	"hundsun.com/hsl/hschain/common/log/logging"
	"hundsun.com/hsl/hschain/protos"
	pbledger "hundsun.com/hsl/hschain/protos/ledger"
	dbm "hundsun.com/hsl/hschain/store/db"
)

// RelayMsgType 中转消息类型
type RelayMsgType uint64

const (
	// UnknownRelayMsg 未知中转消息类型
	UnknownRelayMsg RelayMsgType = iota

	// ConsensusVoteMsg 投票请求
	ConsensusVoteMsg
	// ConsensusVoteRespMsg 投票响应
	ConsensusVoteRespMsg
	// ConsensusCommitMsg 提交请求
	ConsensusCommitMsg
	// ConsensusCommitRespMsg 提交响应
	ConsensusCommitRespMsg
	// ConsensusEndorserMsg 背书请求
	ConsensusEndorserMsg
	// ConsensusEndorserRespMsg 背书响应
	ConsensusEndorserRespMsg

	// BlockSequenceAddBlockMsg 序列化中心添加区块请求
	BlockSequenceAddBlockMsg
	// BlockSequenceAddBlockRespMsg 序列化中心添加区块响应
	BlockSequenceAddBlockRespMsg
	// BlockSequenceRequestMsg 序列化中心请求
	BlockSequenceRequestMsg
	// BlockSequenceResponseMsg 序列化中心响应
	BlockSequenceResponseMsg
)

// ConsensRelayMsg 共识中转消息
type ConsensRelayMsg struct {
	MsgType RelayMsgType
	Payload []byte
}

const (
	// ConsensusTypeSolo solo共识类型
	ConsensusTypeSolo = "solo"
	// ConsensusTypeDpos dpos共识类型
	ConsensusTypeDpos = "dpos"
	// ConsensusTypeRaft raft共识类型
	ConsensusTypeRaft = "raft"
)

const (
	// MaxBlockFee 区块最大费率限制
	MaxBlockFee = 1024000

	// MaxTxCountOfBlock 区块最大交易数限制
	MaxTxCountOfBlock = 1000

	// DefaultMqTimeOut 默认mq超时时间
	DefaultMqTimeOut = 5

	// MilliSecondsPerSecond 每秒钟内的毫秒数
	MilliSecondsPerSecond = 1000
)

// CheckedBlock 模块校验状态
type CheckedBlock struct {
	Block  *pbledger.Block
	Passed bool
}

// BlockCreatorValidator 区块创建者验证函数，校验内容与具体函数有关
type BlockCreatorValidator func(blk *pbledger.Block) (err error)

// BlockAcceptedCallback 区块验证通过后的回调函数
type BlockAcceptedCallback func(blk *pbledger.Block)

// CheckerConfig checker适配器配置对象
type CheckerConfig struct {
	ModuleLog logging.Log

	// BlockCheckInterval 区块验证时间间隔（毫秒），即多久检查一下是否有待验证的块
	BlockCheckInterval int

	// BlockFetchInterval 区块拉取时间间隔（毫秒），即多久没有收到新的区块则主动通知P2P去拉取块
	BlockFetchInterval int

	// PendingBlockPoolFetchSize 一次最多能从pendingPool中获取多少块
	PendingBlockPoolFetchSize int

	// BlockCreatorValidator 验证区块创建者的函数
	BlockCreatorValidator BlockCreatorValidator

	// BlockAcceptedCallback 区块验证通过后的回调函数
	BlockAcceptedCallback BlockAcceptedCallback
}

// ProducerConfig producer相关配置，所有字段均为必须。
type ProducerConfig struct {
	ModuleLog logging.Log

	//MinerAccount 矿工账号
	MinerAccount keystore.Account

	//ProducingInterval 生产2个块之间的时间间隔（毫秒）
	ProducingInterval int

	//MinPendingTxFetchInterval 当从pendingTxPool中获取交易为空或出错时的重试时间间隔（毫秒）
	MinPendingTxFetchInterval int

	//MinCheckBlockExecResultFetchInterval 当获取验证块执行结果哈希为空或者出错时的重试时间间隔（毫秒）
	MinCheckBlockExecResultFetchInterval int
}

// ShouldProceedProducingBlocksFunc 是否应该继续执行ProduceBlocks()方法
type ShouldProceedProducingBlocksFunc func() bool

// BeforeBlockCreatedFunc 出块前调用的方法，主要获取上一块信息用于出块的函数，返回值<上一块的块号,上一块哈希>
type BeforeBlockCreatedFunc func() (lastBlockNumber uint64, lastBlockHash protos.Hash)

// AfterBlockCreatedFunc 出块后调用的方法
type AfterBlockCreatedFunc func(block *pbledger.Block)

const (
	systemParamConsensus  = "con"
	systemParamBlockLimit = "bl"
	systemParamGasLimit   = "gl"
	systemParamFeeLimit   = "fl"
	systemParamTimeLimit  = "tl"
	systemParamReward     = "rwd"
	systemParamDifficulty = "df"
	systemParamCrypto     = "cry"
	systemParamCheckBlock = "ckb"
	systemParamManager    = "mgr"
)

// GenSysParamConsensusPrefix ...
func GenSysParamConsensusPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamConsensus + dbm.PrefixSeparator)
}

// GenSysParamBlockLimitPrefix ...
func GenSysParamBlockLimitPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamBlockLimit + dbm.PrefixSeparator)
}

// GenSysParamGasLimitPrefix ...
func GenSysParamGasLimitPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamGasLimit + dbm.PrefixSeparator)
}

// GenSysParamFeeLimitPrefix ...
func GenSysParamFeeLimitPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamFeeLimit + dbm.PrefixSeparator)
}

// GenSysParamTimeLimitPrefix ...
func GenSysParamTimeLimitPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamTimeLimit + dbm.PrefixSeparator)
}

// GenSysParamRewardPrefix ...
func GenSysParamRewardPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamReward + dbm.PrefixSeparator)
}

// GenSysParamDifficultyPrefix ...
func GenSysParamDifficultyPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamDifficulty + dbm.PrefixSeparator)
}

// GenSysParamCryptoPrefix ...
func GenSysParamCryptoPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamCrypto + dbm.PrefixSeparator)
}

// GenSysParamCheckBlockPrefix ...
func GenSysParamCheckBlockPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamCheckBlock + dbm.PrefixSeparator)
}

// GenSysParamManagerPrefix ...
func GenSysParamManagerPrefix() []byte {
	return []byte(dbm.NamespaceSystemParam + systemParamManager + dbm.PrefixSeparator)
}
